package com.jlf.core.engine.server.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jlf.core.engine.persistence.SchemaCriterionPersistence;
import com.jlf.core.engine.persistence.SchemaDomainPersistence;
import com.jlf.core.engine.domain.SchemaDomainDO;
import com.jlf.core.engine.persistence.SchemaFieldPersistence;
import com.jlf.core.engine.persistence.SchemaIndexPersistence;
import com.jlf.core.engine.query.SchemaDomainQueryInput;
import com.jlf.core.engine.server.SchemaDomainServer;
import com.jlf.core.output.ListResultWrapper;
import com.jlf.core.server.entity.EditRecordWrapper;
import com.jlf.tool.id.SnowflakeId;
import com.jlf.tool.toolkit.StringToolkit;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 领域定义的管理服务
 *
 * @author wujr
 * 2023/7/7
 * @version 1.0
 * 【变更历史】
 * [wujr 2023/7/7 1.0 新增]
 */
@Slf4j
@RequiredArgsConstructor
public class SchemaDomainServerImpl implements SchemaDomainServer {
    private final SchemaDomainPersistence schemaDomainPersistence;
    private final SchemaFieldPersistence schemaFieldPersistence;
    private final SchemaIndexPersistence schemaIndexPersistence;
    private final SchemaCriterionPersistence schemaCriterionPersistence;

    @Override
    public SchemaDomainDO add(SchemaDomainDO record) throws Exception {
        if (StringUtils.isBlank(record.getDomainTable())){
            // 数据表名称为空，根据该模型的编码自动生成
            record.setDomainTable("t_" + StringToolkit.camel2Underline(record.getDomainCode()));
        }else{
            if (!record.getDomainTable().startsWith("t_")){
                record.setDomainTable("t_" + record.getDomainTable());
            }
        }
        record.setId(SnowflakeId.next());
        schemaDomainPersistence.save(record);
        return record;
    }

    @Override
    public void edit(EditRecordWrapper<SchemaDomainDO> wrapper) throws Exception {
        wrapper.getRecord().setId(wrapper.getOriginal().getId());
        if (!StringUtils.isBlank(wrapper.getRecord().getDomainTable()) && !wrapper.getRecord().getDomainTable().startsWith("t_")){
            wrapper.getRecord().setDomainTable("t_" + wrapper.getRecord().getDomainTable());
        }
        schemaDomainPersistence.updateById(wrapper.getRecord());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(SchemaDomainDO record) throws Exception {
        schemaDomainPersistence.removeById(record.getId());
        schemaFieldPersistence.removeByDomain(record.getDomainCode());
        schemaIndexPersistence.removeByDomain(record.getDomainCode());
        schemaCriterionPersistence.removeByDomain(record.getDomainCode());
    }

    @Override
    public ListResultWrapper<SchemaDomainDO> query(SchemaDomainQueryInput input, Integer pageNo, Integer pageSize) {
        QueryWrapper<SchemaDomainDO> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(input.getStatus() != null, SchemaDomainDO::getStatus, input.getStatus())
                .eq(input.getDbIdType() != null, SchemaDomainDO::getDbIdType, input.getDbIdType())
                .eq(input.getOptimisticLocker() != null, SchemaDomainDO::getOptimisticLocker, input.getOptimisticLocker())
                .ge(input.getMinDomainVersion() != null, SchemaDomainDO::getDomainVersion, input.getMinDomainVersion())
                .le(input.getMaxDomainVersion() != null, SchemaDomainDO::getDomainVersion, input.getMaxDomainVersion())
                .and(!StringUtils.isBlank(input.getKey()), w -> w.like(SchemaDomainDO::getDomainCode, input.getKey())
                        .or().like(SchemaDomainDO::getDomainCode, input.getKey())
                        .or().like(SchemaDomainDO::getDomainPackage, input.getKey())
                        .or().like(SchemaDomainDO::getRestfulPath, input.getKey()))
                .orderByAsc(SchemaDomainDO::getPriority)
                .orderByAsc(SchemaDomainDO::getDomainCode);
        if (pageNo < 1 || pageSize < 0){
            // 不分页
            List<SchemaDomainDO> records = schemaDomainPersistence.list(wrapper);
            return new ListResultWrapper<>(records);
        }
        Page<SchemaDomainDO> page = new Page<>(pageNo, pageSize);
        Page<SchemaDomainDO> records = schemaDomainPersistence.page(page, wrapper);
        ListResultWrapper<SchemaDomainDO> output = new ListResultWrapper<>(records.getRecords());
        output.setTotal((int)records.getTotal());
        return output;
    }

}
